import json
import urllib.error
import urllib.parse
import urllib.request


#!/usr/bin/python3
# -*- coding: utf-8 -*-

from configparser import ConfigParser
from hashlib import md5
from http.client import HTTPConnection
from json import loads
from os import path
from random import randint
from sys import exit
from time import sleep
from urllib import parse

from modules.api.base_translation import BaseTranslation
from modules.utils import MY_ERROR_CODES, get_file_encoding, print_err, print_warn

# 常见语种字典
_BAIDU_COMMON_LANGS = [
    'auto',
    'zh',
    'en',
    'yue',
    'wyw',
    'jp',
    'kor',
    'fra',
    'spa',
    'th',
    'ara',
    'ru',
    'pt',
    'de',
    'it',
    'el',
    'nl',
    'pl',
    'bul',
    'est',
    'dan',
    'fin',
    'cs',
    'rom',
    'slo',
    'swe',
    'hu',
    'cht',
    'vie',
]

# 常见源语种字典
_BAIDU_FROM_LANGS = {
    '1': {'n': '自动检测（推荐）', 'c': 'auto'},
    '2': {'n': '中文', 'c': 'zh'},
    '3': {'n': '繁体中文', 'c': 'cht'},
    '4': {'n': '粤语', 'c': 'yue'},
    '5': {'n': '文言文', 'c': 'wyw'},
    '6': {'n': '英语', 'c': 'en'},
    '7': {'n': '日语', 'c': 'jp'},
    '8': {'n': '俄语', 'c': 'ru'},
    '9': {'n': '法语', 'c': 'fra'},
    '10': {'n': '韩语', 'c': 'kor'},
    '11': {'n': '西班牙语', 'c': 'spa'},
    '12': {'n': '泰语', 'c': 'th'},
    '13': {'n': '阿拉伯语', 'c': 'ara'},
    '14': {'n': '葡萄牙语', 'c': 'pt'},
    '15': {'n': '德语', 'c': 'de'},
    '16': {'n': '意大利语', 'c': 'it'},
    '17': {'n': '希腊语', 'c': 'el'},
    '18': {'n': '荷兰语', 'c': 'nl'},
    '19': {'n': '波兰语', 'c': 'pl'},
    '20': {'n': '保加利亚语', 'c': 'bul'},
    '21': {'n': '爱沙尼亚语', 'c': 'est'},
    '22': {'n': '丹麦语', 'c': 'dan'},
    '23': {'n': '芬兰语', 'c': 'fin'},
    '24': {'n': '捷克语', 'c': 'cs'},
    '25': {'n': '罗马尼亚语', 'c': 'rom'},
    '26': {'n': '斯洛文尼亚语', 'c': 'slo'},
    '27': {'n': '瑞典语', 'c': 'swe'},
    '28': {'n': '匈牙利语', 'c': 'hu'},
    '29': {'n': '越南语', 'c': 'vie'},
}

# 常用目标语种字典
_BAIDU_TO_LANGS = {
    '1': {'n': '中文', 'c': 'zh'},
    '2': {'n': '繁体中文', 'c': 'cht'},
    '3': {'n': '粤语', 'c': 'yue'},
    '4': {'n': '文言文', 'c': 'wyw'},
    '5': {'n': '英语', 'c': 'en'},
    '6': {'n': '日语', 'c': 'jp'},
    '7': {'n': '俄语', 'c': 'ru'},
}

# 错误码表
_BAIDU_ERROR_CODES = {
    '52000': '成功',
    '52001': '请求超时！请重试。',
    '52002': '系统错误！请重试。',
    '52003': '未授权用户！请检查appid是否正确或者服务是否开通。',
    '54000': '必填参数为空！请检查是否少传参数。',
    '54001': '签名错误！请检查您的签名生成方法。',
    '54003': '访问频率受限！请降低您的调用频率，或进行身份认证后切换为高级版/尊享版。',
    '54004': '账户余额不足！请前往管理控制台为账户充值。',
    '54005': '长query请求频繁！请降低长query的发送频率，3s后再试。',
    '58000': '客户端IP非法！检查个人资料里填写的IP地址是否正确，可前往开发者信息-基本信息修改。',
    '58001': '译文语言方向不支持！检查译文语言是否在语言列表里。',
    '58002': '服务当前已关闭！请前往管理控制台开启服务。',
    '90107': '认证未通过或未生效！请前往我的认证查看认证进度。',
}


class BaiduTranslation(BaseTranslation):
    '''
    百度通用翻译API,不包含词典、tts语音合成等资源，如有相关需求请联系translate_api@baidu.com
    '''

    def __init__(self, section: str):

        BaseTranslation.__init__(self, section)
        self.section = section

        self._appid = ''
        self._secretKey = ''
        if self._conf and len(self._conf) > 0:
            self._appid = self._conf['appid']
            self._secretKey = self._conf['secretKey']
        if self._appid == '' or self._secretKey == '':
            print_err('翻译API启用失败，请在api_keys.ini中配置appid和secretKey！')
            exit(0)

        self._get_config()

    def translate(
        self, source_txt: str, to_lang: str, from_lang='auto', times=0
    ) -> str:
        '''
        开始翻译

        - source_txt: 输入文本
        - to_lang: 目标语种
        - from_lang: 源语种
        - times: 重试次数
        '''

        # 当源语言不在受支持的语种范围内时，强制将源语言设置为auto，确保翻译能正常进行
        if not from_lang in _BAIDU_COMMON_LANGS:
            from_lang = 'auto'
            print_warn('源语言不在受支持的语种范围内，已强制重置为“自动检测”！')

        # 当源语言不在受支持的语种范围内时，强制将源语言设置为zh，确保翻译能正常进行
        if not to_lang in _BAIDU_COMMON_LANGS:
            to_lang = 'zh'
            print_warn('目标语言不在受支持的语种范围内，已强制重置为“中文”！')

        if to_lang == from_lang:
            print_warn('目标语种和源语种相同。')
            return source_txt

        # 原文本长度超过上限
        if len(source_txt) > self._max_char:
            print_err(MY_ERROR_CODES['ERR_10002'])
            return 'ERR_10002'

        # 重试次数大于3次依然未成功，则返回错误代码
        if times > 3:
            return 'ERR_10001'
        times += 1

        url = 'http://api.niutrans.com/NiuTransServer/translation?'
        data = {
            "from": from_lang,
            "to": to_lang,
            "apikey": self._secretKey,
            "src_text": source_txt,
        }
        data_en = urllib.parse.urlencode(data)
        req = url + "&" + data_en
        res = urllib.request.urlopen(req)
        res = res.read()
        res_dict = json.loads(res)
        if "tgt_text" in res_dict:
            result = res_dict['tgt_text']
        else:
            result = res

        try:
            result = result.decode('utf-8')
        except Exception as e:
            print_err(f'翻译出现异常：{e.args[0]}！')
            target = 'ERR_10001'
        return target

    def _get_config(self):
        '''
        获取配置
        '''

        config_path = path.join(
            path.abspath('.'), 'modules', 'api', 'baidu', 'config.ini'
        )
        if not path.isfile(config_path):
            return

        conf = ConfigParser()  # 调用读取配置模块中的类
        conf.optionxform = lambda option: option
        conf.read(config_path, encoding=get_file_encoding(config_path))

        self._rate = conf.getint(self.section, 'rate')
        if self._rate < 1:
            self._rate = 1
        self._max_char = conf.getint(self.section, 'max_char')
        if self._max_char < 50:
            self._max_char = 2000

    def get_rate(self) -> int:
        '''
        统一函数。获取请求频率
        '''
        return self._rate

    def get_from_langs(self) -> dict:
        '''
        统一函数。获取源语种字典
        '''
        return _BAIDU_FROM_LANGS

    def get_to_langs(self) -> dict:
        '''
        统一函数。获取目标语种字典
        '''
        return _BAIDU_TO_LANGS
